home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 7
/
Amiga Format AFCD07 (Dec 1996, Issue 91).iso
/
serious
/
shareware
/
programming
/
ixemul-complete
/
ixemul
/
library
/
user.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-18
|
7KB
|
348 lines
/*
* This file is part of ixemul.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
* Portions Copyright (C) 1994 Rafael W. Luebbert
* Portions Copyright (C) 1996 Jeff Shepherd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define _KERNEL
#include "ixemul.h"
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#include "multiuser.h"
#include <amitcp/usergroup.h>
static char *
getUserPasswd(char *name)
{
#if 1 /* This gets muFS's password */
/* Only uncomment this when I figure out how ACrypt works */
char *retval = NULL;
char passdir[MAXPATHLEN];
BPTR passwddir = muGetPasswdDirLock();
if (passwddir) {
if (NameFromLock(passwddir, passdir, MAXPATHLEN)) {
if (AddPart(passdir, muPasswd_FileName, MAXPATHLEN)) {
FILE *fi = (FILE *)syscall(SYS_fopen,passdir,"r");
char passwdline[1024];
char username[muUSERNAMESIZE] = {0,};
char passwd[muPASSWORDSIZE] = {0,};
int found_it = 0;
if (fi) {
while (fgets(passwdline,1024,fi)) {
char *sep = strchr(passwdline,'|');
char *old;
strncpy(username,passwdline,sep-passwdline);
old = ++sep;
sep = strchr(old,'|');
strncpy(passwd,old,sep - old);
if (!strcmp(username,name)) {
found_it = 1;
break;
}
}
if (found_it) {
retval = strdup(passwd);
}
fclose(fi);
}
}
}
UnLock(passwddir);
}
if (!retval)
retval = strdup("*");
return retval;
#else
/* Use the network's password */
struct passwd *pwd = netcall(NET_getpwnam,name);
char *retval;
if (pwd)
retval = strdup(pwd->pw_passwd);
else
retval = strdup("*");
return retval;
#endif
}
/* multiuser doesn't allow a password entry for nobody (uid = 0)
* I will create one though
*/
static struct muUserInfo nobody_userinfo = {
"nobody",
0,
0,
"nobody",
"t:",
0,
(UWORD *)NULL,
"cli",
};
static struct passwd *
UserInfo2pw (struct muUserInfo *UI)
{
struct passwd *pw = &u.u_passwd;
if (UI == NULL)
return NULL;
pw->pw_name = UI->UserID;
pw->pw_dir = UI->HomeDir;
#if 1
if (pw->pw_passwd)
free(pw->pw_passwd);
pw->pw_passwd = getUserPasswd(pw->pw_name);
#else
pw->pw_passwd = "*";
#endif
pw->pw_uid = UI->uid;
pw->pw_gid = UI->gid;
pw->pw_change = 0;
pw->pw_class = 0;
pw->pw_gecos = UI->UserName;
pw->pw_shell = UI->Shell;
pw->pw_expire = 0;
return pw;
}
uid_t
getuid(void)
{
if (muBase)
return (muGetTaskOwner(NULL) >> 16);
if (u.u_ixnetbase)
return netcall(NET_getuid);
return 0;
}
uid_t
geteuid(void)
{
if (muBase)
return getuid();
if (u.u_ixnetbase)
return netcall(NET_geteuid);
return 0;
}
int
setuid (uid_t uid)
{
int retval = 0;
if (muBase)
{
if (getuid() == muROOT_UID)
{
struct muUserInfo *UI = muAllocUserInfo();
if (UI) {
UI->uid = uid;
UI = muGetUserInfo (UI, muKeyType_uid);
if (muLogin(muT_Task, (ULONG)FindTask(NULL),
muT_UserID, (ULONG)UI->UserID,
muT_NoLog, TRUE,
TAG_DONE)) {
u.u_setuid++;
}
muFreeUserInfo(UI);
}
}
else {
errno = EPERM;
retval = -1;
}
return retval;
/* I don't think usergroup + muFS need to setuid */
/* uid = MU2UG(uid); */
}
if (u.u_ixnetbase)
return netcall(NET_setuid, uid);
else
/* just always succeed... */
return retval;
}
int
seteuid (uid_t uid)
{
if (u.u_ixnetbase)
return netcall(NET_seteuid, uid);
else
return setuid(uid);
}
int
setreuid (int ruid, int euid)
{
if (u.u_ixnetbase)
return netcall(NET_setreuid, ruid, euid);
else
return setuid(euid);
}
struct passwd *getpwuid (uid_t uid)
{
char *name;
struct passwd *retval;
if (muBase)
{
/* active multiuser */
struct muUserInfo *UI = u.u_UserInfo;
UI->uid = uid;
/*
* "nobody" can't have a password entry
* so I will create one
*/
UI = (uid == muOWNER_NOBODY ? &nobody_userinfo : muGetUserInfo (UI, muKeyType_uid));
return UserInfo2pw (UI); /* handles errors */
}
if (u.u_ixnetbase)
return (struct passwd *)netcall(NET_getpwuid, uid);
if ((name = (char *)syscall(SYS_getenv, "USER")))
retval = (struct passwd *)syscall(SYS_getpwnam, name);
else
retval = (struct passwd *)syscall(SYS_getpwnam, "root");
retval->pw_uid = uid;
return retval;
}
struct passwd *getpwnam (const char *name)
{
/* this is not quite safe, since this library function could be called
* in parallel with different names... well, I don't consider this worth
* doing `right', it's here to be able to link some programs ;-)
*/
static struct passwd pw = {
0, /* pw_name */
"*", /* pw_passwd */
0, /* pw_uid */
0, /* pw_gid */
0, /* pw_change */
0, /* pw_class */
0, /* pw_dir */
0, /* pw_gecos */
"/bin/sh", /* pw_shell */
0 /* pw_expire */
};
if (muBase)
{
struct muUserInfo *UI = u.u_UserInfo;
/*
* some validation checks
*/
if (name == NULL)
return NULL;
if ((muUSERIDSIZE - 1) < strlen (name))
return NULL;
strcpy (UI->UserID, name);
UI = muGetUserInfo (UI, muKeyType_UserID);
/* special case for nobody (uid 0) */
/* Not sure if this should come before muGetUserInfo()
* since nobody could have another uid
*/
if (!UI && !strcmp(name,"nobody"))
UI = &nobody_userinfo;
return UserInfo2pw (UI); /* handles errors */
}
if (u.u_ixnetbase)
return (struct passwd *)netcall(NET_getpwnam, name);
pw.pw_name = (char *)name;
if (!(pw.pw_dir = (char *)syscall(SYS_getenv, "HOME"))) {
pw.pw_dir = "SYS:";
}
if (!(pw.pw_gecos = (char *)syscall(SYS_getenv, "REALNAME"))) {
pw.pw_gecos = "amiga user";
}
return &pw;
}
struct passwd *
getpwent(void)
{
char *name;
if (!muBase && u.u_ixnetbase)
return (struct passwd *)netcall(NET_getpwent);
name = getenv("USER");
if (name)
return (struct passwd *)syscall(SYS_getpwnam, name);
return (struct passwd *)syscall(SYS_getpwnam, "root");
}
int
setpassent(int stayopen)
{
if (u.u_ixnetbase)
return netcall(NET_setpassent, stayopen);
return 1;
}
int
setpwent(void)
{
if (u.u_ixnetbase)
return netcall(NET_setpwent);
return 1 ;
}
void
endpwent(void)
{
if (u.u_ixnetbase)
netcall(NET_endpwent);
}
pid_t
setsid(void)
{
if (u.u_ixnetbase)
return (pid_t)netcall(NET_setsid);
else {
errno = EPERM;
return -1;
}
}